package com.zzr.demo.redis.service.impl;

import com.zzr.demo.redis.service.SessionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.el.lang.ELArithmetic;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @author: xiaomi
 * @date: 2021/10/8
 * @description: 不验证重复 userId
 */
@Service
@Slf4j
public class SessionServiceImpl implements SessionService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Override
    public String createSession(String userId) {
        HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();
        String token = generateToken();
        //HSET 并没有过期的参数，所以需要设置两个
        opsForHash.put(TOKEN_HASH_KEY, userId, token);
        long timestamp = LocalDateTime.now().plusMinutes(5).toInstant(ZoneOffset.of("+8")).toEpochMilli();
        //HSET 转为时间戳,NOTEME value 需要设置String
        opsForHash.put(TOKEN_EXPIRE_HASH_KEY, userId, timestamp + "");
        log.info("token:userId:{},token:{}", userId, token);
        log.info("token_expire:userId:{},expire:{}", userId, timestamp);
        return token;
    }

    @Override
    public String validate(String userId, String token) {
        HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();
        Object tk = opsForHash.get(TOKEN_HASH_KEY, userId);
        if (tk == null) {
            return SESSION_NOT_LOGIN;
        }
        if (tk.toString().equals(token)) {
            Object expire = opsForHash.get(TOKEN_EXPIRE_HASH_KEY, userId);
            long exp = Long.parseLong(expire.toString());
            log.info("get expire:{}", exp);
            if (exp > System.currentTimeMillis()) {
                return SESSION_TOKEN_CORRECT;
            } else {
                return SESSION_EXPIRE;
            }
        } else {
            return SESSION_TOKEN_INCORRECT;
        }
    }

    @Override
    public boolean destroy(String userId) {
        HashOperations<String, Object, Object> opsForHash = stringRedisTemplate.opsForHash();
        opsForHash.delete(TOKEN_HASH_KEY, userId);
        opsForHash.delete(TOKEN_EXPIRE_HASH_KEY, userId);
        return true;
    }

    String generateToken() {
        return UUID.randomUUID().toString();
    }
}
